const assert = require('assert');
const crypto = require('crypto');
const CryptoJS = require('crypto-js');

const throwError = (code, message) => {
  const err = new Error(message);
  err.code = code;
  throw err;
};

// 加密
const encryptText = text => {
  const hash = crypto.createHash('sha256');
  hash.update(`${text}-${Date.now()}`);
  const uniqueText = `${hash.digest('hex')}`;
  return uniqueText;
};

// 获取唯一的文件名
const generateUniqueFileName = file => {
  const extension = file.name.split('.').pop();
  const hash = crypto.createHash('sha256');
  hash.update(`${file.name}-${file.size}-${Date.now()}`);
  const uniqueFileName = `${hash.digest('hex')}.${extension}`;
  return uniqueFileName;
};

// save sql转化
const saveSqlParse = saveData => {
  let fields = [];
  let values = [];
  for (let key in saveData) {
    if (key != 'id') {
      fields.push(key);
      // values.push(`'${saveData[key]}'`);

      // 处理不同类型的值
      if (saveData[key] === null || saveData[key] === undefined) {
        values.push('NULL');
      } else if (typeof saveData[key] === 'number') {
        values.push(saveData[key]);
      } else {
        values.push(`'${saveData[key]}'`);
      }
    }
  }
  return {
    fields,
    values,
  };
};

// save多条 sql转化
const saveAllSqlParse = (saveData, defaultField = []) => {
  const valList = []; // 所有参数值集合
  const fields = []; // 字段
  const values = []; // 值
  for (let i = 0; i < saveData.length; i++) {
    let item = saveData[i];
    values.length = 0;
    for (let key in item) {
      if (i == 0) {
        fields.push(key);
      }
      if (defaultField.length == 0) {
        values.push(`'${item[key]}'`);
      } else if (defaultField.includes(key)) {
        values.push(`'${item[key]}'`);
      }
    }
    valList.push(`(${values.join(',')})`);
  }

  if (defaultField.length > 0) {
    fields.length = 0;
    fields.push(...defaultField);
  }

  return {
    fields,
    valList,
  };
};

// update sql转化
const updateSqlParse = saveData => {
  const sqlArr = [];
  for (let key in saveData) {
    if (key != 'id') {
      console.log(saveData[key] != '');
      if (objectAttrHas(saveData, key) && saveData[key] !== '') {
        sqlArr.push(`${key}='${saveData[key]}'`);
      } else {
        sqlArr.push(`${key}=null`);
      }
    }
  }

  return sqlArr;
};

// 判断对象属性是否存在
const objectAttrHas = (obj, key) => {
  return Object.prototype.hasOwnProperty.call(obj, key);
};

/**
 * CryptoJS 加密
 *
 * @param {String} encryptData  需要加密数据
 * @returns 加密后的数据
 * @memberof Utils
 */
const encrypt = encryptData => {
  //定制秘钥，长度必须为： 8/16/32位
  var key = CryptoJS.enc.Utf8.parse('ac123456');
  var srcs = CryptoJS.enc.Utf8.parse(encryptData);
  var encrypted = CryptoJS.AES.encrypt(srcs, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  });
  return encrypted.toString();
};

/**
 * CryptoJS 解密
 *
 * @param {String} encryptData  需要加密数据
 * @returns 解密后的数据
 * @memberof Utils
 */
const decrypt = encryptData => {
  //定制秘钥，长度必须为： 8/16/32位
  var key = CryptoJS.enc.Utf8.parse('ac123456');
  var decrypt = CryptoJS.AES.decrypt(encryptData, key, {
    mode: CryptoJS.mode.ECB,
    padding: CryptoJS.pad.Pkcs7,
  });
  return CryptoJS.enc.Utf8.stringify(decrypt).toString();
};

/**
 * 加载env配置
 */
const loadEnv = () => {
  const fs = require('fs');
  const NODE_ENV = process.env.NODE_ENV;

  // 根据环境来读取配置文件（本地环境和对应的环境）
  const dotenvFiles = [`.env.${NODE_ENV}`, `.env`].filter(Boolean);

  // 遍历文件注入所有环境变量（这里就把配置文件的变量注入到process.env中了，只是node环境可访问）
  dotenvFiles.forEach(dotenvFile => {
    if (fs.existsSync(dotenvFile)) {
      require('dotenv').config({
        path: dotenvFile,
      });
    }
  });
};

module.exports = {
  assert,
  throwError,
  generateUniqueFileName,
  saveSqlParse,
  updateSqlParse,
  saveAllSqlParse,
  objectAttrHas,
  encrypt,
  decrypt,
  loadEnv
};
